package ar.republicagroup.gestion.services.impl;

import ar.republicagroup.gestion.dao.CalendarioBancarioDAO;
import ar.republicagroup.gestion.dao.ChequePenalizacionDAO;
import ar.republicagroup.gestion.dao.LiquidacionDAO;
import ar.republicagroup.gestion.entities.Cheque;
import ar.republicagroup.gestion.entities.ChequeEstado;
import ar.republicagroup.gestion.entities.ChequePenalizacion;
import ar.republicagroup.gestion.entities.Cliente;
import ar.republicagroup.gestion.entities.Liquidacion;
import ar.republicagroup.gestion.entities.LiquidacionDetalle;
import ar.republicagroup.gestion.services.ChequeEstadoServices;
import ar.republicagroup.gestion.services.ChequeServices;
import ar.republicagroup.gestion.services.ClienteServices;
import ar.republicagroup.gestion.services.LiquidacionServices;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import org.apache.log4j.Logger;

/**
 *
 * @author DIEGOALV
 */
public class LiquidacionServicesImpl implements LiquidacionServices{
    
    LiquidacionDAO liquidacionDao;
    ChequePenalizacionDAO chequePenalizacionDao;
    CalendarioBancarioDAO calendarioBancarioDao;
    
    private double totalValoresAlCobroVC    = 0;
    private double totalValoresAlCobroCAP   = 0;
    private double totalComGestion          = 0;
    /* Suma del total por penalización de rechazado  1*/
    private double totalRechazo1            = 0;
     /* Suma del total por penalización de rechazado 2*/
    private double totalRechazo2            = 0;
    private double totalLiquidacion         = 0;
    private double totalRechazados          = 0;     
    
    private double totalRechazosCAP         = 0;
    private double totalRechazosVC          = 0;
    
    private double comisionChequesVC        = 0;
    private double comisionChequesCAP       = 0;
    
    /* Sumatoria de cheques por Liquidacion */
    
    private int nroDeChequesLiquidados = 0;
    private int nroDeChequesRechazados = 0;
    private int nroDeChequesPendientes = 0;
    
    private Cliente cliente;
    
    Logger log = Logger.getLogger(LiquidacionServicesImpl.class);
    
    
    @Override
    public List<Liquidacion> findEntities() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public List<Liquidacion> getLiquidacionsByFilters(Cliente cliente, Date fechaDesde, Date fechaHasta) {
        return liquidacionDao.getLiquidacionsByFilters(cliente, fechaDesde, fechaHasta);
    }

    @Override
    public String insert(Liquidacion beanLiquidacion) {
        return liquidacionDao.insert(beanLiquidacion);
    }

    @Override
    public String update(Liquidacion beanLiquidacion) {
        return liquidacionDao.update(beanLiquidacion);
    }

    @Override
    public Liquidacion get(Integer id_cheque) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public String delete(Integer id_cheque) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    
    
    /* BUSSINNES LOGIC */
    @Override
    public void addChequeToLiquidacion(Cheque cheque) {
            double multaPorRechazo = 0;
            /* Obtengo la multa correspondiente al estado del cheque . Sólo para cheques rechazados, el resto devuelve null */
            ChequePenalizacion multa = chequePenalizacionDao.getChequePenalizacionByChequeEstado(cheque.getChequeEstadoId());
         
            if(multa != null)
             {
                 multaPorRechazo     = multa.getComision();
             }    

            if(cheque.getOrigen().equals(ChequeServices.ORIGEN_VC)){
                comisionChequesVC   = cheque.getComision().doubleValue();
            }  else {
                comisionChequesCAP  = cheque.getComision().doubleValue();
            }  
            
            String tieneComRechazo = cheque.getBolsaChequeId().getClienteId().getComisionRechazo();
            
            
        /* Suma de totales de acuerdo al estado del cheque */                
        switch(cheque.getChequeEstadoId().getId()){
            case CHEQUE_APROBADO: 
            case CHEQUE_LIQUIDADO:      if(cheque.getOrigen().equals(ChequeServices.ORIGEN_VC)){
                                            totalValoresAlCobroVC   += cheque.getImporte().doubleValue();
                                        }else{
                                            totalValoresAlCobroCAP  +=  cheque.getImporte().doubleValue();
                                        }
                                    
                                    totalComGestion    += (cheque.getImporte().doubleValue() * (cheque.getComision().doubleValue()/100)); 
                                    nroDeChequesLiquidados++;
                                    break;            
            
            case CHEQUE_RECHAZADO_1: totalRechazo1 += multaPorRechazo;    
                                     nroDeChequesRechazados++;
                                     if(cheque.getGestionEnRechazos().equals(ClienteServices.TIENE_COMISION_RECHAZO)){
                                        if(cheque.getOrigen().equals(ChequeServices.ORIGEN_VC)){
                                            totalRechazosVC += cheque.getImporte().doubleValue();
                                        } else {
                                            totalRechazosCAP += cheque.getImporte().doubleValue();
                                        }
                                     
                                     totalComGestion         += (cheque.getImporte().doubleValue() * (cheque.getComision().doubleValue()/100));
                                     }
                                     break;
            
            case CHEQUE_RECHAZADO_2: totalRechazo2 += multaPorRechazo;    
                                     nroDeChequesRechazados++;
                                     
                                     if(cheque.getGestionEnRechazos().equals(ClienteServices.TIENE_COMISION_RECHAZO)){
                                        if(cheque.getOrigen().equals(ChequeServices.ORIGEN_VC)){
                                            totalRechazosVC += cheque.getImporte().doubleValue();
                                        } else {
                                            totalRechazosCAP += cheque.getImporte().doubleValue();
                                        }
                                     
                                        totalComGestion         += (cheque.getImporte().doubleValue() * (cheque.getComision().doubleValue()/100));
                                     }
                                     break;
                
            case CHEQUE_RECHAZADO_3: nroDeChequesRechazados++;
                                    if(cheque.getGestionEnRechazos().equals(ClienteServices.TIENE_COMISION_RECHAZO)){
                                        if(cheque.getOrigen().equals(ChequeServices.ORIGEN_VC)){
                                            totalRechazosVC += cheque.getImporte().doubleValue();
                                        } else {
                                            totalRechazosCAP += cheque.getImporte().doubleValue();
                                        }
                                     
                                        totalComGestion         += (cheque.getImporte().doubleValue() * (cheque.getComision().doubleValue()/100));
                                     }
                                     break;     
            
            case CHEQUE_POSTERGADO : nroDeChequesPendientes++;
                                     break;    
        }
        
        
    }
    
    @Override
    public List<LiquidacionDetalle> convertirChequesAListDeDetalle(List<Cheque> chequeList, Liquidacion liquidacion) {
                List<LiquidacionDetalle> liquidacionDetalleList = new ArrayList<>();
                
                for(Cheque cheque : chequeList){
                       LiquidacionDetalle detalle = new LiquidacionDetalle();
                        detalle.setChequeId(cheque);
                        detalle.setLiquidacionId(liquidacion);
                        
                          if(cheque.getChequeEstadoId().getId() == CHEQUE_APROBADO){
                            cheque.setChequeEstadoId(new ChequeEstado(CHEQUE_LIQUIDADO));
                            cheque.setFechaLiquidado(Calendar.getInstance().getTime());
                            detalle.setChequeEstadoId(new ChequeEstado(CHEQUE_LIQUIDADO));
                           
                            } else if(cheque.getChequeEstadoId().getId() == CHEQUE_RECHAZADO_1  || 
                                  cheque.getChequeEstadoId().getId() == CHEQUE_RECHAZADO_2      ||
                                  cheque.getChequeEstadoId().getId() == CHEQUE_RECHAZADO_3  ) 
                                            {
                                            ChequePenalizacion multa = chequePenalizacionDao.getChequePenalizacionByChequeEstado(cheque.getChequeEstadoId());
                                            cheque.setChequePenalizacion(multa);
                                            cheque.setFechaLiquidado(Calendar.getInstance().getTime());
                                            detalle.setChequeEstadoId(cheque.getChequeEstadoId());
                                            } 
                                                else if(cheque.getChequeEstadoId().getId() == ChequeEstadoServices.CHEQUE_PENDIENTE){
                                                    detalle.setChequeEstadoId(cheque.getChequeEstadoId());
                                            }
                            detalle.setEstado(1);
                            liquidacionDetalleList.add(detalle);
                }   
       return liquidacionDetalleList;
    }
    
    @Override
    public double calcularSaldoActual(double importePagado, double totalDeLiquidacion, double saldoLiquidacionAnterior) {
        return importePagado - (totalDeLiquidacion + saldoLiquidacionAnterior);
    }
    

    @Override
    public double getTotalValoresAlCobroVC() {
        return totalValoresAlCobroVC;
    }

    public void setTotalValoresAlCobroProv(double totalValoresAlCobroVC) {
        this.totalValoresAlCobroVC = totalValoresAlCobroVC;
    }

    @Override
    public double getTotalValoresAlCobroCAP() {
        return totalValoresAlCobroCAP;
    }

    public void setTotalValoresAlCobroCap(double totalValoresAlCobroCAP) {
        this.totalValoresAlCobroCAP = totalValoresAlCobroCAP;
    }

    @Override
    public double getTotalComGestion() {
        return totalComGestion;
    }

    public void setTotalComGestion(double totalComGestion) {
        this.totalComGestion = totalComGestion;
    }

    @Override
    public double getTotalRechazo1() {
        return totalRechazo1;
    }

    public void setTotalRechazo1(double totalRechazo1) {
        this.totalRechazo1 = totalRechazo1;
    }

    @Override
    public double getTotalRechazo2() {
        return totalRechazo2;
    }

    public void setTotalRechazo2(double totalRechazo2) {
        this.totalRechazo2 = totalRechazo2;
    }

    @Override
    public double getTotalLiquidacion() {
        log.info("Calculando total de liquidación...");
        totalLiquidacion = (totalValoresAlCobroCAP + totalRechazosCAP + totalValoresAlCobroVC + totalRechazosVC) - totalRechazosCAP - totalRechazosVC - totalComGestion - totalRechazo1 - totalRechazo2;
        log.info("Total de liquidación : "+totalLiquidacion);
        return totalLiquidacion;
        
    }

    public void setTotalLiquidacion(double totalLiquidacion) {
        this.totalLiquidacion = totalLiquidacion;
    }

    @Override
    public double getTotalRechazados() {
        totalRechazados  = totalRechazo1 + totalRechazo2;
        return  totalRechazados;
    }

    public void setTotalRechazados(double totalRechazados) {
        this.totalRechazados = totalRechazados;
    }
 
    @Override
    public double getSaldoActual() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    
    @Override
    public int getNroDeChequesLiquidados() {
       return nroDeChequesLiquidados;
    }

    @Override
    public int getNroDeChequesRechazados() {
       return nroDeChequesRechazados;
    }

    @Override
    public int getNroDeChequesPendientes() {
       return nroDeChequesPendientes;
    }
    
    
    
    /* Inyeccion de dependencias por setter */
   public void setLiquidacionDao(LiquidacionDAO liquidacionDao) {
        this.liquidacionDao = liquidacionDao;
    }

    public void setChequePenalizacionDao(ChequePenalizacionDAO chequePenalizacionDao) {
        this.chequePenalizacionDao = chequePenalizacionDao;
    }

    

    
    @Override
    public void reiniciarTotales() {
        setTotalComGestion(0);
        setTotalLiquidacion(0);
        setTotalRechazados(0);
        setTotalRechazo1(0);
        setTotalRechazo2(0);
        setTotalValoresAlCobroCap(0);
        setTotalValoresAlCobroProv(0);
        nroDeChequesLiquidados = 0;
        nroDeChequesRechazados = 0;
        nroDeChequesPendientes = 0;
        totalRechazosCAP       = 0;
        totalRechazosVC        = 0;
        
    }

    @Override
    public int getNroTotalDeCheques() {
       return nroDeChequesLiquidados + nroDeChequesPendientes + nroDeChequesRechazados;
    }

    @Override
    public double getTotalRechazosCAP() {
       return totalRechazosCAP;
    }

    @Override
    public double getTotalRechazosVC() {
       return totalRechazosVC;
    }

    /*Total de los montos por cheques rechazados (rechazos por motivo 1 2 y 3) */
    @Override
    public double getTotalRechazos() {
        return totalRechazosCAP + totalRechazosVC;
    }

    @Override
    public double getSubtotalGestion() {
       return getSubtotalCAP() + getSubtotalVC();
    }

    @Override
    public void setCliente(Cliente cliente) {
       this.cliente = cliente;
    }

    @Override
    public Cliente getCliente() {
        return cliente;
    }
 
    @Override
    public double getSubtotalCAP() {
      return  (getTotalValoresAlCobroCAP() + getTotalRechazosCAP()) * ((100 - getComisionCAP())/100); 
    }

    @Override
    public double getSubtotalVC() {
      return  (getTotalValoresAlCobroVC() + getTotalRechazosVC()) * ((100 - getComisionVC())/100); 
    }

    @Override
    public double getComisionVC() {
       return comisionChequesVC;
    }

    @Override
    public double getComisionCAP() {
       return comisionChequesCAP;
    }

    @Override
    public Liquidacion getLastLiquidacionByCliente(Cliente cliente) {
       return liquidacionDao.getLastLiquidacionByCliente(cliente);
    }

    
    
   
}
